#ifndef ALIAODMUONREPLICATOR0_H
#define ALIAODMUONREPLICATOR0_H

/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
* See cxx source for full Copyright notice                               */

// $Id: AliAODMuonReplicator.h 56492 2012-05-15 18:42:47Z pcrochet $


#ifndef ALIDAODBRANCHREPLICATOR_H
#  include "AliAODBranchReplicator.h"
#endif
#ifndef ROOT_TExMap
#  include "TExMap.h"
#endif


#ifndef AliAOD3LH_H
#include "AliAOD3LH.h"
#endif

//#include "AliAOD3LH.h" 

//
// Implementation of a branch replicator 
// to produce slim muon and dimuon aods.
//
// Author: L. Aphecetche (Subatech)

class AliAnalysisCuts;
class TClonesArray;
class AliAODMCHeader;
class AliAODVZERO;
class AliAODTZERO;
class AliPIDResponse;
class AliESDv0;
class TArrayI;
class AliAODv0;  
class TRefArray;
class AliAODRecoDecay;
class AliAODRecoDecayHF;
class AliAODRecoDecayHF2Prong;
class AliVertexerTracks;

class AliESDVertex;
class AliESDtrack;
class AliVEvent;
class AliAODVertex;
class AliVertexerTracks;
class AliESDv0; 
class AliAODv0; 

class TH1F;

class AliAODMuonReplicator0 : public AliAODBranchReplicator
{
 public:
  
  AliAODMuonReplicator0(const char* name="AliAODMuonReplicator0", 
			const char* title="Branch Replicator for muon related branches",
			AliAnalysisCuts* trackCut=0x0,
			AliAnalysisCuts* vertexCut=0x0,
			Int_t mcMode=0,
			Int_t nsigmaTrk1=3, Int_t partType1 = 2,
			Int_t nsigmaTrk2=3, Int_t partType2 = 7);
  
  //  Int_t partType; // 0 = e; 1 = mu; 2 = pi; 3 = K; 4= p; 5 = d; 6 =t ; 7 = 3He; 8=4He;

  virtual ~AliAODMuonReplicator0();
  
  virtual TList* GetList() const;
  
  virtual void ReplicateAndFilter(const AliAODEvent& source);
  
  virtual void Terminate();

 private:

  void FilterMC(const AliAODEvent& source);
  void SelectParticle(Int_t i);
  Bool_t IsParticleSelected(Int_t i);
  void CreateLabelMap(const AliAODEvent& source);
  Int_t GetNewLabel(Int_t i);
  Double_t fBzkG;     // z componenent of field in kG
  Int_t fAODMapSize;  // size of fAODMap 
  Int_t *fAODMap;     //[fAODMapSize] map between index and ID for AOD tracks
  AliVertexerTracks* fVertexerTracks; // vertexer, to compute secondary vertices
  AliESDVertex *fV1;   // primary vertex

  Double_t fCosMin       ;
  Double_t fDCAtracksMin ;
  Double_t fRmax         ;
  Double_t fRmin         ;
  Double_t fDNmin        ;
  Double_t fDPmin        ;

 private:
  
  AliAnalysisCuts* fTrackCut; // decides which tracks to keep
  mutable TClonesArray* fTracks; //! internal array of muon tracks
  TClonesArray& fV0s(); //! 

  AliAnalysisCuts* fVertexCut; // decides which vertices to keep
  mutable TClonesArray* fVertices; //! internal array of vertices
  mutable TClonesArray* fDimuons; //! internal array of dimuons
  mutable TClonesArray* fVZERO; //! internal vzero object
  mutable AliAODTZERO* fTZERO; //! internal tzero object
  mutable TList* fList; //! internal list of managed objects (fVertices and fTracks)
  
  mutable TClonesArray* fMCParticles; //! internal array of MC particles
  mutable AliAODMCHeader* fMCHeader; //! internal array of MC header
  Int_t fMCMode; // MC filtering switch (0=none=no mc information,1=normal=simple copy,>=2=aggressive=filter out)

  Int_t fnSigmaTrk1;
  Int_t fnSigmaTrk2;
  Int_t fpartType1;
  Int_t fpartType2;

  TExMap fLabelMap; //! for MC label remapping (in case of aggressive filtering)
  TExMap fParticleSelected; //! List of selected MC particles

  Bool_t fSecVtxWithKF; // if kTRUE use KF vertexer, else AliVertexerTracks

  AliAODVertex* ReconstructSecondaryVertex(TObjArray *trkArray,Double_t &dispersion,Bool_t useTRefArray=kTRUE) const;
  //  AliAODRecoDecayHF2Prong* Make2Prong(TObjArray *twoTrackArray,AliVEvent &event, AliAODVertex *secVert,Double_t dca, Int_t *charge[2]) ;
  //  AliAODRecoDecayHF2Prong* Make2Prong(TObjArray *twoTrackArray,AliVEvent &event, AliAODVertex *secVert,Double_t dca) ;
  
  AliAODRecoDecayHF2Prong* Make2Prong(TObjArray *twoTrackArray,const AliAODEvent &evento,
				      AliAODVertex *secVert,Double_t dca);
  

  void AddDaughterRefs(AliAODVertex *v, const AliAODEvent &event, const TObjArray *trkArray) const;
  void AddRefs(AliAODVertex *v,AliAODRecoDecayHF *rd, const AliAODEvent &event, const TObjArray *trkArray) const;
 private:

  //  AliPIDResponse  *fPIDResponse;                  //! PID response object
  
  AliAODMuonReplicator0(const AliAODMuonReplicator0&);
  AliAODMuonReplicator0& operator=(const AliAODMuonReplicator0&);
  
  ClassDef(AliAODMuonReplicator0,5) // Branch replicator for ESD to muon AOD.
    };

#endif
